const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CssMinimizer = require('css-minimizer-webpack-plugin')
const Terser = require('terser-webpack-plugin')

module.exports = {
    /*
     指定打包的模式：production生产环境、development开发环境
       默认情况下，开发环境打包后的内容不压缩，方便调试，而生产环境是压缩混淆的
       在代码中，我们可以基于 process.env.NODE_ENV 获取环境变量值
     */
    mode: 'production',
    entry: './src/index.js',
    output: {
        filename: 'bundle.[hash:8].js',
        path: path.resolve(__dirname, 'dist')
    },
    /* 使用插件 */
    plugins: [
        // 作用：打包HTML页面；把打包后的bundle包，自动导入到html中...
        new HtmlWebpackPlugin({
            title: '珠峰培训-webpack学习',
            template: './public/index.html',
            favicon: './public/favicon.ico',
            minify: true
        }),
        // 作用：清除之前打包的内容
        new CleanWebpackPlugin(),
        // 作用：抽离CSS单独进行打包
        new MiniCssExtractPlugin({
            filename: 'bundle.[hash:8].css'
        })
    ],
    /* DEV-SERVER */
    devServer: {
        host: '127.0.0.1',
        port: 3000,
        compress: true,
        open: true,
        proxy: {
            // 知乎服务器的代理
            '/api': {
                target: 'https://news-at.zhihu.com',
                changeOrigin: true
            },
            // 简书服务器的代理
            '/inst': {
                target: 'https://www.jianshu.com',
                changeOrigin: true,
                pathRewrite: { '^/inst': '' }
            }
        }
    },
    /* 
    使用Loader
      + 如果使用很多Loader，则处理顺序：从下->上 、从右->左...
      + include: 指定只对哪些目录进行编译  path.resolve(__dirname, 'src')
      + exclude: 指定哪些文件不编译  /node_modules/
    */
    module: {
        rules: [
            // 处理Css&Less的
            {
                test: /\.(css|less)$/i,
                exclude: /node_modules/,
                use: [
                    // 'style-loader', //把编译后的css以内嵌式插入到页面中
                    MiniCssExtractPlugin.loader,
                    'css-loader', //处理css中的页数语法，例如：url...
                    'postcss-loader', //给css设置前缀，以此来实现浏览器兼容
                    'less-loader'  //把less编译为css
                ]
            },
            // 处理JS
            {
                test: /\.(js|jsx|ts|tsx)$/i,
                include: path.resolve(__dirname, 'src'),
                use: ['babel-loader'],
                /* use: [{
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }] */
            }
        ]
    },
    /* 优化项 */
    optimization: {
        minimizer: [
            new CssMinimizer(),
            new Terser()
        ]
    },
    /* 解析器 */
    resolve: {
        alias: {
            '@/': path.resolve(__dirname, 'src/')
        }
    }
}


/*
 在前端项目中，我们需要考虑的兼容问题：
   我们首先需要设置浏览器兼容列表 https://github.com/browserslist/browserslist
   "browserslist": [
      "> 1%",
      "last 2 versions",
      "not ie <= 9"
   ]

   + CSS3样式的兼容「思路：设置前缀」
     postcss-loader + autoprefixer + browserslist
   + ES6语法的兼容「思路：转换为ES5」
     babel/babel-loader + @babel/preset-env + browserslist
     有一些特殊的语法，需要我们安装babel中单独的插件来完成
   + ES6内置API的兼容「思路：对方法重写」 
     @babel/polyfill
     但不是所有的内置API都重写了！！
 */